Aller au contenu principal

Cours Avancé : optimiser ses builds d'image

Bien choisir son image de base un choix complexe (et partiellement subjectif ?)

Beaucoup de personnes utilisent des images de base construites à partir de alpine qui est un bon compromis (6 mégaoctets seulement et un gestionnaire de paquets apk). Mais ce choix a aussi ses inconvénients:

Les images basées sur debian-slim et redhat ubi-micro sont a peine plus lourde et probablement plus solide/sécurisées et polyvalentes.

A mentionner: les images de base distroless : un projet de Google des images linux Debian de base mais sans tout ce qui fait la distribution (notamment apt) => a utiliser pour injecter les elements prébuildé dans un build multistage.

  • avantage encore plus léger et moins de surface d'attaque
  • images plus difficiles à patcher pour des failles car on ne peut pas utiliser le travail de la distribution

Pour s'y retrouver on peut se référer à ce comparatif assez complet (bien que pro-redhat) : https://crunchtools.com/comparison-linux-container-images/

Autre comparaison pour faire des images minimales: https://baykara.medium.com/alpine-vs-distroless-vs-busybox-e14573ba8724

Pour entrer dans les détails d'une image on peut installer et utiliser https://github.com/wagoodman/dive. C'est souvent nécessaire quand on optimiser au maximum son image d'avoir conscience de tous les fichiers

Cache de Build

Utilisation optimale du cache de build

La documentation officielle est plutôt claire à ce sujet: https://docs.docker.com/build/cache/

Cache et CI/CD

Un enjeu du cache est notamment d'accélérer l'exécution du build dans les pipelines de CI/CD. Pour celà on peut utiliser un cache de build distant, par exemple avec le backend registry de Buildkit : https://docs.docker.com/build/cache/backends/#backends

Essayer les builds multistage parallélisés

Une comparaison des autre outils de build d'image

Docker Buildkit

Est le (nouveau) builder par défaut de Docker depuis quelques années.

  • Très performant, parallélisé, cache intelligent dans des multistage builds.

  • Peut être étendu et configuré avec le nouveau gestionnaire buildx pour notamment:

  • Inconvénient : pour les CI/CD il faut du Docker in Docker qui pas idéal en terme de sécurité voire impossible dans certains contextes (un cluster K8s sans docker).

Builder plusieurs images pour plusieurs architectures avec buildx

Buildx est un plugin Docker assez récent qui permet d'automatiser le build d'images et de builder pour plusieurs architectures.

Tutoriel d'exemple : https://www.docker.com/blog/how-to-rapidly-build-multi-architecture-images-with-buildx/

Kaniko:

Outil de Google pour builder efficacement sans Docker à partir d'un Dockerfile, notamment dans un cluster Kubernetes. Tourné vers la CI/CD Permet de pousser le cache des build vers un serveur pour ne pas le perdre quand le build est réalisé dans un agent on demand temporaire (Jenkins in K8s par exemple)

Le gros avantage est de pouvoir builder avec n'importe quelle runtime de conteneur (c'est un peu risqué d'être dépendant de Docker pour le futur ?)

Buildah

Un builder initialement de RedHat désormais maintenu par l'Open Container Initiative (respecte encore plus directement les standards ouverts de conteneurs)

Un builder automatique plus récent et exotique : Buildpacks

Cette solution package automatiquement le code source d'une application en detectant ses dépendance et sa structure. C'est très puissant.

  • Avantage : les bonnes pratiques sont garanties par les recettes automatiques (quand elle on été codées par des spécialistes et revues par les pairs)
  • les images sont optimisées (si le buildpack aka la recette est pas nulle)
  • Meilleure reproductibilité des builds

Inconvénients:

  • Ça fait des boites noires un peu magiques il faut faire confiance si on a pas codé le buildpack qui automatise
  • Il faut qu'un buildpack existe ou en coder un => c'est plus compliqué que Dockerfile

Tutorial : Apprendre le bas niveau des images Docker en les construisants "à la main"

Quelques références: